package com.financial.service.heemoney.aspect;

import com.financial.service.heemoney.annotation.NotEmpty;
import com.financial.service.heemoney.annotation.NotNull;
import com.financial.service.heemoney.annotation.ValidateParam;
import com.financial.service.heemoney.utils.apiresult.ApiResult;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.List;


/**
 * @Author: wenguoqiang
 * @Email wguoqiango@163.com
 * @Date: 2019/12/13 0013 下午 4:16
 * @Des
 */
@Aspect
@Component
public class ValidateParamAspect {


    @Pointcut("@annotation(com.financial.service.heemoney.annotation.ValidateParam)")
    public void validatePoint() {

    }

    @Around(value = "validatePoint() && @annotation(validateParam)")
    public Object checkParam(ProceedingJoinPoint proceedingJoinPoint, ValidateParam validateParam) {
        Object result = null;
        Object[] args = proceedingJoinPoint.getArgs();
        String[] annoStr = validateParam.value();
        try {
            result = ParamValidate(args, annoStr);
            if(result != null){
                return result;
            }
            result = proceedingJoinPoint.proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        return result;
    }

    private ApiResult ParamValidate(Object[] paramObj, String[] annoValue) throws Exception {
        for (String className : annoValue) {
            for (Object arg : paramObj) {
                Class classObj = arg.getClass();
                if (className.equals(classObj.getName())) {
                    //TODO
                    Field[] fields = classObj.getDeclaredFields();
                    for (Field field : fields) {

                        if (field.isAnnotationPresent(NotNull.class)) {
                            field.setAccessible(true);
                            Object fieldValue = field.get(arg);
                            NotNull notNull = field.getDeclaredAnnotation(NotNull.class);
                            String[] ifNullFields = notNull.ifNullField();
                            if (isValidateParam(arg, classObj, ifNullFields) && fieldValue == null) {
                                return ApiResult.failure(String.format("参数%s 不为null", field.getName()));
                            }

                        } else if (field.isAnnotationPresent(NotEmpty.class)) {
                            field.setAccessible(true);
                            Object fieldValue = field.get(arg);
                            NotEmpty notEmpty = field.getDeclaredAnnotation(NotEmpty.class);
                            String[] ifNullFields =  notEmpty.ifNullField();

                            if (isValidateParam(arg, classObj, ifNullFields) && (fieldValue == null || StringUtils.isBlank(fieldValue.toString())))
                                return ApiResult.failure(String.format("参数%s 不为空（“” 或者 null）", field.getName()));
                        }

                    }

                }

            }
        }
        return null;
    }
    private boolean isValidateParam(Object arg, Class classObj, String[] ifNullFields) throws NoSuchFieldException, IllegalAccessException {

        if (ifNullFields.length > 0) {
            for (String ifNullFeildName : ifNullFields) {
                Field inNullFeild = classObj.getDeclaredField(ifNullFeildName);
                inNullFeild.setAccessible(true);
                Object inNullFeildValue = inNullFeild.get(arg);
                if (inNullFeildValue == null || (inNullFeildValue instanceof String && StringUtils.isBlank(inNullFeildValue.toString())))
                    return true;
                else
                    return false;
            }

        }
        return true;
    }
}
